home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / news / inn1.000 / inn1.4sec-linux-src.tar / inn / lib / dbz.pch < prev    next >
Text File  |  1993-02-03  |  25KB  |  1,000 lines

  1. DBZ as distributed by CNEWS has a few bits of lint in it.  They fall into
  2. the following categories:
  3.     1.  There is code after return statements, like
  4.         return(value);
  5.         break;
  6.     2.  If you turn off DBZDEBUG some fluff is left behind.
  7.     3.  A couple of (void) casts should be added to fprintf calls
  8.         since ferror is checked right after.
  9.     4.  Use "clibrary.h" for many C library declarations, and the
  10.         POINTER typedef found there.
  11. In addition, DBZ cannot be used with vfork.  (Yes, I agree with all the
  12. other purists that vfork is a crock, but I'm a realist enough to recognize
  13. that it can get some major performance benefits if used in innd.) Applying
  14. this patch makes sure that any files that DBZ opens have the close-on-exec
  15. flag set.
  16.  
  17. This patch also includes two performance enhancements by Rob Robertson
  18. <rob@violet.berkeley.edu>.  The first is the new dbzwritethrough() routine
  19. that makes the incore mode of DBZ use a write-through cache.  The second
  20. is automatic calculation of the database tags; Craig Leres
  21. <leres@ee.lbl.gov> contributed dbztagmask() based on Rob's code.
  22.  
  23. This patch also includes the option to memory-map the database using the
  24. mmap() call.  This original version of that code was by David Robinson,
  25. formerly <david@elroy.jpl.nasa.gov> now <david.robinson@sun.com> (January,
  26. 1993).
  27.  
  28. Apply the following diff by using the "patch" program.  The Makefile
  29. will normally do this for you automatically.
  30.  
  31. DBZ is great, and Jon and Henry (and the others mentioned in the source)
  32. deserve a lot of credit for it.
  33.  
  34. *** ../dbz/dbz.c    Wed Oct 16 10:50:15 1991
  35. --- dbz.c    Fri Jan 22 09:34:06 1993
  36. ***************
  37. *** 12,17 ****
  38. --- 12,24 ----
  39.   
  40.   Major reworking by Henry Spencer as part of the C News project.
  41.   
  42. + Minor lint and CodeCenter (Saber) fluff removal by Rich $alz (March, 1991).
  43. + Non-portable CloseOnExec() calls added by Rich $alz (September, 1991).
  44. + Added "writethrough" and tagmask calculation code from
  45. + <rob@violet.berkeley.edu> and <leres@ee.lbl.gov> by Rich $alz (December, 1992).
  46. + Merged in MMAP code by David Robinson, formerly <david@elroy.jpl.nasa.gov>
  47. + now <david.robinson@sun.com> (January, 1993).
  48.   These routines replace dbm as used by the usenet news software
  49.   (it's not a full dbm replacement by any means).  It's fast and
  50.   simple.  It contains no AT&T code.
  51. ***************
  52. *** 24,30 ****
  53.   
  54.   #include <stdio.h>
  55.   #include <sys/types.h>
  56. ! #include <string.h>
  57.   #include <ctype.h>
  58.   #include <errno.h>
  59.   #ifndef __STDC__
  60. --- 31,37 ----
  61.   
  62.   #include <stdio.h>
  63.   #include <sys/types.h>
  64. ! #include <sys/stat.h>
  65.   #include <ctype.h>
  66.   #include <errno.h>
  67.   #ifndef __STDC__
  68. ***************
  69. *** 31,36 ****
  70. --- 38,44 ----
  71.   extern int errno;
  72.   #endif
  73.   #include <dbz.h>
  74. + #include "clibrary.h"
  75.   
  76.   /*
  77.    * #ifdef index.  "LIA" = "leave it alone unless you know what you're doing".
  78. ***************
  79. *** 50,56 ****
  80. --- 58,67 ----
  81.    * MAXRUN    length of run which shifts to next table (see below) (LIA)
  82.    * OVERFLOW    long-int arithmetic overflow must be avoided, will trap
  83.    * NOBUFFER    do not buffer hash-table i/o, B News locking is defective
  84. +  * MMAP        Use SunOS style mmap() for efficient incore
  85.    */
  86. + /* SUPPRESS 530 *//* Empty body for statement */
  87. + /* SUPPRESS 701 on free *//* Conflicting declaration */
  88.   
  89.   #ifdef FUNNYSEEKS
  90.   #include <unistd.h>
  91. ***************
  92. *** 203,208 ****
  93. --- 214,237 ----
  94.   static void mybytemap();
  95.   static of_t bytemap();
  96.   
  97. + /*
  98. +  * Using mmap() is a more efficent way of keeping the .pag file incore.  On
  99. +  * average, it cuts the number of system calls and buffer copies in half.
  100. +  * It also allows one copy to be shared among many processes without
  101. +  * consuming any extra resources.
  102. +  */
  103. + #ifdef MMAP
  104. + #include <sys/mman.h>
  105. + #ifdef MAP_FILE
  106. + #define MAP__ARG    (MAP_FILE | MAP_SHARED)
  107. + #else
  108. + #define MAP__ARG    (MAP_SHARED)
  109. + #endif
  110. + #ifndef INCORE
  111. + #define INCORE
  112. + #endif
  113. + #endif
  114.   /* 
  115.    * For a program that makes many, many references to the database, it
  116.    * is a large performance win to keep the table in core, if it will fit.
  117. ***************
  118. *** 228,233 ****
  119. --- 257,270 ----
  120.   #endif
  121.   
  122.   /*
  123. +  * Write to filesystem even if incore?  This replaces a single multi-
  124. +  * megabyte write when doing a dbzsync with a multi-byte write each
  125. +  * time an article is added.  On most systems, this will give an overall
  126. +  * performance boost.
  127. +  */
  128. + static int writethrough = 0;
  129. + /*
  130.    * Stdio buffer for .pag reads.  Buffering more than about 16 does not help
  131.    * significantly at the densities we try to maintain, and the much larger
  132.    * buffers that most stdios default to are much more expensive to fill.
  133. ***************
  134. *** 298,316 ****
  135.    * alternative (under most compilers) is to pack around 2K of unused
  136.    * strings -- there's just no way to get rid of them.
  137.    */
  138. - static int debug;            /* controlled by dbzdebug() */
  139.   #ifdef DBZDEBUG
  140. ! #define DEBUG(args) if (debug) { (void) printf args ; }
  141.   #else
  142.   #define    DEBUG(args)    ;
  143.   #endif
  144.   
  145.   /* externals used */
  146.   extern char *malloc();
  147.   extern char *calloc();
  148.   extern void free();        /* ANSI C; some old implementations say int */
  149.   extern int atoi();
  150.   extern long atol();
  151.   
  152.   /* misc. forwards */
  153.   static long hash();
  154. --- 335,358 ----
  155.    * alternative (under most compilers) is to pack around 2K of unused
  156.    * strings -- there's just no way to get rid of them.
  157.    */
  158.   #ifdef DBZDEBUG
  159. ! static int debug;            /* controlled by dbzdebug() */
  160. ! #define DEBUG(args) if (debug) { (void) printf args ; } else
  161.   #else
  162.   #define    DEBUG(args)    ;
  163.   #endif
  164.   
  165.   /* externals used */
  166. + #if    0
  167. + extern char *memcpy();
  168. + extern char *memchr();
  169.   extern char *malloc();
  170.   extern char *calloc();
  171.   extern void free();        /* ANSI C; some old implementations say int */
  172. + #endif    /* 0 */
  173.   extern int atoi();
  174.   extern long atol();
  175. + extern void CloseOnExec();
  176.   
  177.   /* misc. forwards */
  178.   static long hash();
  179. ***************
  180. *** 336,342 ****
  181. --- 378,386 ----
  182.   static of_t *corepag;        /* incore version of .pag file, if any */
  183.   static FILE *bufpagf;        /* well-buffered pagf, for incore rewrite */
  184.   static of_t *getcore();
  185. + #ifndef MMAP
  186.   static int putcore();
  187. + #endif
  188.   static int written;        /* has a store() been done? */
  189.   
  190.   /*
  191. ***************
  192. *** 391,399 ****
  193.       default:
  194.           DEBUG(("dbzfresh case map `%c' unknown\n", cmap));
  195.           return(-1);
  196. -         break;
  197.       }
  198. !     switch (tagmask) {
  199.       case 0:            /* default */
  200.           break;
  201.       case 1:            /* no tags */
  202. --- 435,442 ----
  203.       default:
  204.           DEBUG(("dbzfresh case map `%c' unknown\n", cmap));
  205.           return(-1);
  206.       }
  207. !     switch ((int)tagmask) {
  208.       case 0:            /* default */
  209.           break;
  210.       case 1:            /* no tags */
  211. ***************
  212. *** 418,424 ****
  213.       if (fn == NULL)
  214.           return(-1);
  215.       f = fopen(fn, "w");
  216. !     free(fn);
  217.       if (f == NULL) {
  218.           DEBUG(("dbzfresh: unable to write config\n"));
  219.           return(-1);
  220. --- 461,467 ----
  221.       if (fn == NULL)
  222.           return(-1);
  223.       f = fopen(fn, "w");
  224. !     free((POINTER)fn);
  225.       if (f == NULL) {
  226.           DEBUG(("dbzfresh: unable to write config\n"));
  227.           return(-1);
  228. ***************
  229. *** 437,443 ****
  230.       if (fn == NULL)
  231.           return(-1);
  232.       f = fopen(fn, "w");
  233. !     free(fn);
  234.       if (f == NULL) {
  235.           DEBUG(("dbzfresh: unable to create/truncate .pag file\n"));
  236.           return(-1);
  237. --- 480,486 ----
  238.       if (fn == NULL)
  239.           return(-1);
  240.       f = fopen(fn, "w");
  241. !     free((POINTER)fn);
  242.       if (f == NULL) {
  243.           DEBUG(("dbzfresh: unable to create/truncate .pag file\n"));
  244.           return(-1);
  245. ***************
  246. *** 522,527 ****
  247. --- 565,572 ----
  248.       register FILE *f;
  249.       register int newtable;
  250.       register of_t newsize;
  251. +     struct stat sb;
  252. +     register of_t m;
  253.   
  254.       if (pagf != NULL) {
  255.           DEBUG(("dbzagain: database already open\n"));
  256. ***************
  257. *** 533,539 ****
  258.       if (fn == NULL)
  259.           return(-1);
  260.       f = fopen(fn, "r");
  261. !     free(fn);
  262.       if (f == NULL) {
  263.           DEBUG(("dbzagain: cannot open old .dir file\n"));
  264.           return(-1);
  265. --- 578,584 ----
  266.       if (fn == NULL)
  267.           return(-1);
  268.       f = fopen(fn, "r");
  269. !     free((POINTER)fn);
  270.       if (f == NULL) {
  271.           DEBUG(("dbzagain: cannot open old .dir file\n"));
  272.           return(-1);
  273. ***************
  274. *** 545,550 ****
  275. --- 590,608 ----
  276.           return(-1);
  277.       }
  278.   
  279. +     /* calculate tagging from old file */
  280. +     if (stat(oldname, &sb) != -1) {
  281. +          for (m = 1, i = 0; m < sb.st_size; i++, m <<= 1)
  282. +              continue;
  283. +          
  284. +          /* if we had more tags than the default, use the new data */
  285. +          if ((c.tagmask | c.tagenb) && m > (1 << TAGSHIFT)) {
  286. +               c.tagshift = i;
  287. +               c.tagmask = (~(unsigned long)0) >> (i + 1);
  288. +               c.tagenb = (c.tagmask << 1) & ~c.tagmask;
  289. +          }
  290. +     }
  291.       /* tinker with it */
  292.       top = 0;
  293.       newtable = 0;
  294. ***************
  295. *** 570,576 ****
  296.       if (fn == NULL)
  297.           return(-1);
  298.       f = fopen(fn, "w");
  299. !     free(fn);
  300.       if (f == NULL) {
  301.           DEBUG(("dbzagain: unable to write new .dir\n"));
  302.           return(-1);
  303. --- 628,634 ----
  304.       if (fn == NULL)
  305.           return(-1);
  306.       f = fopen(fn, "w");
  307. !     free((POINTER)fn);
  308.       if (f == NULL) {
  309.           DEBUG(("dbzagain: unable to write new .dir\n"));
  310.           return(-1);
  311. ***************
  312. *** 587,593 ****
  313.       if (fn == NULL)
  314.           return(-1);
  315.       f = fopen(fn, "w");
  316. !     free(fn);
  317.       if (f == NULL) {
  318.           DEBUG(("dbzagain: unable to create/truncate .pag file\n"));
  319.           return(-1);
  320. --- 645,651 ----
  321.       if (fn == NULL)
  322.           return(-1);
  323.       f = fopen(fn, "w");
  324. !     free((POINTER)fn);
  325.       if (f == NULL) {
  326.           DEBUG(("dbzagain: unable to create/truncate .pag file\n"));
  327.           return(-1);
  328. ***************
  329. *** 629,639 ****
  330.           dirronly = 1;
  331.       } else
  332.           dirronly = 0;
  333. !     free(dirfname);
  334.       if (dirf == NULL) {
  335.           DEBUG(("dbminit: can't open .dir file\n"));
  336.           return(-1);
  337.       }
  338.   
  339.       /* open the .pag file */
  340.       pagfname = enstring(name, pag);
  341. --- 687,698 ----
  342.           dirronly = 1;
  343.       } else
  344.           dirronly = 0;
  345. !     free((POINTER)dirfname);
  346.       if (dirf == NULL) {
  347.           DEBUG(("dbminit: can't open .dir file\n"));
  348.           return(-1);
  349.       }
  350. +     CloseOnExec((int)fileno(dirf), 1);
  351.   
  352.       /* open the .pag file */
  353.       pagfname = enstring(name, pag);
  354. ***************
  355. *** 647,653 ****
  356.           if (pagf == NULL) {
  357.               DEBUG(("dbminit: .pag open failed\n"));
  358.               (void) fclose(dirf);
  359. !             free(pagfname);
  360.               return(-1);
  361.           }
  362.           pagronly = 1;
  363. --- 706,712 ----
  364.           if (pagf == NULL) {
  365.               DEBUG(("dbminit: .pag open failed\n"));
  366.               (void) fclose(dirf);
  367. !             free((POINTER)pagfname);
  368.               return(-1);
  369.           }
  370.           pagronly = 1;
  371. ***************
  372. *** 655,660 ****
  373. --- 714,721 ----
  374.           pagronly = 1;
  375.       else
  376.           pagronly = 0;
  377. +     if (pagf != NULL)
  378. +         CloseOnExec((int)fileno(pagf), 1);
  379.   #ifdef NOBUFFER
  380.       /*
  381.        * B News does not do adequate locking on its database accesses.
  382. ***************
  383. *** 679,690 ****
  384.           if (basefname == NULL) {
  385.               (void) fclose(pagf);
  386.               (void) fclose(dirf);
  387. !             free(pagfname);
  388.               pagf = NULL;
  389.               return(-1);
  390.           }
  391.       } else
  392.           basefname = NULL;
  393.   #ifdef _IOFBF
  394.       if (basef != NULL)
  395.           (void) setvbuf(basef, basebuf, _IOFBF, sizeof(basebuf));
  396. --- 740,753 ----
  397.           if (basefname == NULL) {
  398.               (void) fclose(pagf);
  399.               (void) fclose(dirf);
  400. !             free((POINTER)pagfname);
  401.               pagf = NULL;
  402.               return(-1);
  403.           }
  404.       } else
  405.           basefname = NULL;
  406. +     if (basef != NULL)
  407. +         CloseOnExec((int)fileno(basef), 1);
  408.   #ifdef _IOFBF
  409.       if (basef != NULL)
  410.           (void) setvbuf(basef, basebuf, _IOFBF, sizeof(basebuf));
  411. ***************
  412. *** 696,702 ****
  413.           (void) fclose(basef);
  414.           (void) fclose(pagf);
  415.           (void) fclose(dirf);
  416. !         free(pagfname);
  417.           pagf = NULL;
  418.           errno = EDOM;    /* kind of a kludge, but very portable */
  419.           return(-1);
  420. --- 759,765 ----
  421.           (void) fclose(basef);
  422.           (void) fclose(pagf);
  423.           (void) fclose(dirf);
  424. !         free((POINTER)pagfname);
  425.           pagf = NULL;
  426.           errno = EDOM;    /* kind of a kludge, but very portable */
  427.           return(-1);
  428. ***************
  429. *** 714,726 ****
  430.       s = (size_t)conf.tsize * SOF;
  431.       if (incore && (of_t)(s/SOF) == conf.tsize) {
  432.           bufpagf = fopen(pagfname, (pagronly) ? "rb" : "r+b");
  433. !         if (bufpagf != NULL)
  434.               corepag = getcore(bufpagf);
  435.       } else {
  436.           bufpagf = NULL;
  437.           corepag = NULL;
  438.       }
  439. !     free(pagfname);
  440.   
  441.       /* misc. setup */
  442.       crcinit();
  443. --- 777,791 ----
  444.       s = (size_t)conf.tsize * SOF;
  445.       if (incore && (of_t)(s/SOF) == conf.tsize) {
  446.           bufpagf = fopen(pagfname, (pagronly) ? "rb" : "r+b");
  447. !         if (bufpagf != NULL) {
  448.               corepag = getcore(bufpagf);
  449. +             CloseOnExec((int)fileno(bufpagf), 1);
  450. +         }
  451.       } else {
  452.           bufpagf = NULL;
  453.           corepag = NULL;
  454.       }
  455. !     free((POINTER)pagfname);
  456.   
  457.       /* misc. setup */
  458.       crcinit();
  459. ***************
  460. *** 775,781 ****
  461.           ret = -1;
  462.       }
  463.       if (corepag != NULL)
  464. !         free((char *)corepag);
  465.       corepag = NULL;
  466.       if (fclose(basef) == EOF) {
  467.           DEBUG(("dbmclose: fclose(basef) failed\n"));
  468. --- 840,853 ----
  469.           ret = -1;
  470.       }
  471.       if (corepag != NULL)
  472. ! #ifdef MMAP
  473. !         if (munmap(corepag, (int)conf.tsize * SOF) == -1) {
  474. !             DEBUG(("dbmclose: munmap failed\n"));
  475. !             ret = -1;
  476. !         }
  477. ! #else
  478. !         free((POINTER)corepag);
  479. ! #endif
  480.       corepag = NULL;
  481.       if (fclose(basef) == EOF) {
  482.           DEBUG(("dbmclose: fclose(basef) failed\n"));
  483. ***************
  484. *** 782,788 ****
  485.           ret = -1;
  486.       }
  487.       if (basefname != NULL)
  488. !         free(basefname);
  489.       basef = NULL;
  490.       pagf = NULL;
  491.       if (fclose(dirf) == EOF) {
  492. --- 854,860 ----
  493.           ret = -1;
  494.       }
  495.       if (basefname != NULL)
  496. !         free((POINTER)basefname);
  497.       basef = NULL;
  498.       pagf = NULL;
  499.       if (fclose(dirf) == EOF) {
  500. ***************
  501. *** 809,820 ****
  502.       if (!written)
  503.           return(0);
  504.   
  505. !     if (corepag != NULL) {
  506.           if (putcore(corepag, bufpagf) < 0) {
  507.               DEBUG(("dbzsync: putcore failed\n"));
  508.               ret = -1;
  509.           }
  510.       }
  511.       if (!conf.olddbz)
  512.           if (putconf(dirf, &conf) < 0)
  513.               ret = -1;
  514. --- 881,894 ----
  515.       if (!written)
  516.           return(0);
  517.   
  518. ! #ifndef MMAP
  519. !     if (corepag != NULL && !writethrough) {
  520.           if (putcore(corepag, bufpagf) < 0) {
  521.               DEBUG(("dbzsync: putcore failed\n"));
  522.               ret = -1;
  523.           }
  524.       }
  525. + #endif
  526.       if (!conf.olddbz)
  527.           if (putconf(dirf, &conf) < 0)
  528.               ret = -1;
  529. ***************
  530. *** 922,928 ****
  531.               DEBUG(("fetch: seek failed\n"));
  532.               return(output);
  533.           }
  534. !         if (fread(buffer, 1, keysize, basef) != keysize) {
  535.               DEBUG(("fetch: read failed\n"));
  536.               return(output);
  537.           }
  538. --- 996,1002 ----
  539.               DEBUG(("fetch: seek failed\n"));
  540.               return(output);
  541.           }
  542. !         if (fread((POINTER)buffer, 1, keysize, basef) != keysize) {
  543.               DEBUG(("fetch: read failed\n"));
  544.               return(output);
  545.           }
  546. ***************
  547. *** 932,938 ****
  548.           (void) mapcase(buffer, buffer, keysize);
  549.           DEBUG(("fetch: buffer (%s) looking for (%s) size = %d\n", 
  550.                           buffer, key.dptr, keysize));
  551. !         if (memcmp(key.dptr, buffer, cmplen) == 0 &&
  552.                   (*sepp == conf.fieldsep || *sepp == '\0')) {
  553.               /* we found it */
  554.               output.dptr = (char *)&key_ptr;
  555. --- 1006,1012 ----
  556.           (void) mapcase(buffer, buffer, keysize);
  557.           DEBUG(("fetch: buffer (%s) looking for (%s) size = %d\n", 
  558.                           buffer, key.dptr, keysize));
  559. !         if (memcmp((POINTER)key.dptr, (POINTER)buffer, cmplen) == 0 &&
  560.                   (*sepp == conf.fieldsep || *sepp == '\0')) {
  561.               /* we found it */
  562.               output.dptr = (char *)&key_ptr;
  563. ***************
  564. *** 965,976 ****
  565.           DEBUG(("latebase: still can't open base\n"));
  566.       } else {
  567.           DEBUG(("latebase: late open succeeded\n"));
  568. !         free(basefname);
  569.           basefname = NULL;
  570.   #ifdef _IOFBF
  571.           (void) setvbuf(it, basebuf, _IOFBF, sizeof(basebuf));
  572.   #endif
  573.       }
  574.       return(it);
  575.   }
  576.   
  577. --- 1039,1052 ----
  578.           DEBUG(("latebase: still can't open base\n"));
  579.       } else {
  580.           DEBUG(("latebase: late open succeeded\n"));
  581. !         free((POINTER)basefname);
  582.           basefname = NULL;
  583.   #ifdef _IOFBF
  584.           (void) setvbuf(it, basebuf, _IOFBF, sizeof(basebuf));
  585.   #endif
  586.       }
  587. +     if (it != NULL)
  588. +         CloseOnExec((int)fileno(it), 1);
  589.       return(it);
  590.   }
  591.   
  592. ***************
  593. *** 1034,1040 ****
  594.       }
  595.   
  596.       /* copy the value in to ensure alignment */
  597. !     (void) memcpy((char *)&value, data.dptr, SOF);
  598.       DEBUG(("store: (%s, %ld)\n", key.dptr, (long)value));
  599.       if (!okayvalue(value)) {
  600.           DEBUG(("store: reserved bit or overflow in 0x%lx\n", value));
  601. --- 1110,1116 ----
  602.       }
  603.   
  604.       /* copy the value in to ensure alignment */
  605. !     (void) memcpy((POINTER)&value, (POINTER)data.dptr, SOF);
  606.       DEBUG(("store: (%s, %ld)\n", key.dptr, (long)value));
  607.       if (!okayvalue(value)) {
  608.           DEBUG(("store: reserved bit or overflow in 0x%lx\n", value));
  609. ***************
  610. *** 1062,1072 ****
  611. --- 1138,1188 ----
  612.   {
  613.       register int old = incore;
  614.   
  615. + #ifndef MMAP
  616.       incore = value;
  617. + #endif
  618.       return(old);
  619.   }
  620.   
  621.   /*
  622. +  - dbzwritethrough - write through the pag file in core
  623. +  */
  624. + int                /* old setting */
  625. + dbzwritethrough(value)
  626. + int value;
  627. + {
  628. +     register int old = writethrough;
  629. +     writethrough = value;
  630. +     return(old);
  631. + }
  632. + /*
  633. +  - dbztagmask - calculate the correct tagmask for the given base file size
  634. +  */
  635. + long
  636. + dbztagmask(size)
  637. + register long size;
  638. + {
  639. +     register long m;
  640. +     register long tagmask;
  641. +     register int i;
  642. +     if (size <= 0)
  643. +         return(0L);        /* silly size */
  644. +     for (m = 1, i = 0; m < size; i++, m <<= 1)
  645. +         continue;
  646. +     if (m < (1 << TAGSHIFT))
  647. +         return(0L);        /* not worth tagging */
  648. +     tagmask = (~(unsigned long)0) >> (i + 1);
  649. +     tagmask = tagmask << i;
  650. +     return(tagmask);
  651. + }
  652. + /*
  653.    - getconf - get configuration from .dir file
  654.    */
  655.   static int            /* 0 success, -1 failure */
  656. ***************
  657. *** 1107,1113 ****
  658.       if (getno(df, &err) != dbzversion)
  659.           err = -1;
  660.       cp->tsize = getno(df, &err);
  661. !     cp->fieldsep = getno(df, &err);
  662.       while ((c = getc(df)) == ' ')
  663.           continue;
  664.       cp->casemap = c;
  665. --- 1223,1229 ----
  666.       if (getno(df, &err) != dbzversion)
  667.           err = -1;
  668.       cp->tsize = getno(df, &err);
  669. !     cp->fieldsep = (int)getno(df, &err);
  670.       while ((c = getc(df)) == ' ')
  671.           continue;
  672.       cp->casemap = c;
  673. ***************
  674. *** 1124,1129 ****
  675. --- 1240,1246 ----
  676.           cp->bytemap[i] = getno(df, &err);
  677.       if (getc(df) != '\n')
  678.           err = -1;
  679. + #ifdef DBZDEBUG
  680.       DEBUG(("size %ld, sep %d, cmap %c, tags 0x%lx/0x%lx<<%d, ", cp->tsize,
  681.               cp->fieldsep, cp->casemap, cp->tagenb, cp->tagmask,
  682.               cp->tagshift));
  683. ***************
  684. *** 1132,1137 ****
  685. --- 1249,1255 ----
  686.           DEBUG((" %d", cp->bytemap[i]));
  687.       }
  688.       DEBUG(("\n"));
  689. + #endif
  690.   
  691.       /* second line, the usages */
  692.       for (i = 0; i < NUSEDS; i++)
  693. ***************
  694. *** 1201,1214 ****
  695.           DEBUG(("fseek failure in putconf\n"));
  696.           ret = -1;
  697.       }
  698. !     fprintf(f, "dbz %d %ld %d %c %ld %ld %d %d", dbzversion, cp->tsize,
  699.                   cp->fieldsep, cp->casemap, cp->tagenb,
  700.                   cp->tagmask, cp->tagshift, cp->valuesize);
  701.       for (i = 0; i < cp->valuesize; i++)
  702. !         fprintf(f, " %d", cp->bytemap[i]);
  703. !     fprintf(f, "\n");
  704.       for (i = 0; i < NUSEDS; i++)
  705. !         fprintf(f, "%ld%c", cp->used[i], (i < NUSEDS-1) ? ' ' : '\n');
  706.   
  707.       (void) fflush(f);
  708.       if (ferror(f))
  709. --- 1319,1332 ----
  710.           DEBUG(("fseek failure in putconf\n"));
  711.           ret = -1;
  712.       }
  713. !     (void) fprintf(f, "dbz %d %ld %d %c %ld %ld %d %d", dbzversion, cp->tsize,
  714.                   cp->fieldsep, cp->casemap, cp->tagenb,
  715.                   cp->tagmask, cp->tagshift, cp->valuesize);
  716.       for (i = 0; i < cp->valuesize; i++)
  717. !         (void) fprintf(f, " %d", cp->bytemap[i]);
  718. !     (void) fprintf(f, "\n");
  719.       for (i = 0; i < NUSEDS; i++)
  720. !         (void) fprintf(f, "%ld%c", cp->used[i], (i < NUSEDS-1) ? ' ' : '\n');
  721.   
  722.       (void) fflush(f);
  723.       if (ferror(f))
  724. ***************
  725. *** 1229,1235 ****
  726. --- 1347,1378 ----
  727.       register size_t i;
  728.       register size_t nread;
  729.       register char *it;
  730. + #ifdef MMAP
  731. +     struct stat st;
  732.   
  733. +     if (fstat(fileno(f), &st) == -1) {
  734. +         DEBUG(("getcore: fstat failed\n"));
  735. +         return(NULL);
  736. +     }
  737. +     if (((size_t)conf.tsize * SOF) > st.st_size) {
  738. +         /* file too small; extend it */
  739. +         if (ftruncate((int)fileno(f), conf.tsize * SOF) == -1) {
  740. +             DEBUG(("getcore: ftruncate failed\n"));
  741. +             return(NULL);
  742. +         }
  743. +     }
  744. +     it = mmap((caddr_t)0, (size_t)conf.tsize * SOF, 
  745. +         pagronly ? PROT_READ : PROT_WRITE | PROT_READ, MAP__ARG,
  746. +         (int)fileno(f), (off_t)0);
  747. +     if (it == (char *)-1) {
  748. +         DEBUG(("getcore: mmap failed\n"));
  749. +         return(NULL);
  750. +     }
  751. + #ifdef MC_ADVISE
  752. +     /* not present in all versions of mmap() */
  753. +     madvise(it, (size_t)conf.tsize * SOF, MADV_RANDOM);
  754. + #endif
  755. + #else
  756.       it = malloc((size_t)conf.tsize * SOF);
  757.       if (it == NULL) {
  758.           DEBUG(("getcore: malloc failed\n"));
  759. ***************
  760. *** 1236,1255 ****
  761.           return(NULL);
  762.       }
  763.   
  764. !     nread = fread(it, SOF, (size_t)conf.tsize, f);
  765.       if (ferror(f)) {
  766.           DEBUG(("getcore: read failed\n"));
  767. !         free(it);
  768.           return(NULL);
  769.       }
  770.   
  771.       p = (of_t *)it + nread;
  772.       i = (size_t)conf.tsize - nread;
  773.       while (i-- > 0)
  774.           *p++ = VACANT;
  775.       return((of_t *)it);
  776.   }
  777.   
  778.   /*
  779.    - putcore - try to rewrite an in-core table
  780.    */
  781. --- 1379,1402 ----
  782.           return(NULL);
  783.       }
  784.   
  785. !     nread = fread((POINTER)it, SOF, (size_t)conf.tsize, f);
  786.       if (ferror(f)) {
  787.           DEBUG(("getcore: read failed\n"));
  788. !         free((POINTER)it);
  789.           return(NULL);
  790.       }
  791.   
  792. +      /* NOSTRICT *//* Possible pointer alignment problem */
  793.       p = (of_t *)it + nread;
  794.       i = (size_t)conf.tsize - nread;
  795.       while (i-- > 0)
  796.           *p++ = VACANT;
  797. + #endif
  798. +      /* NOSTRICT *//* Possible pointer alignment problem */
  799.       return((of_t *)it);
  800.   }
  801.   
  802. + #ifndef MMAP
  803.   /*
  804.    - putcore - try to rewrite an in-core table
  805.    */
  806. ***************
  807. *** 1262,1271 ****
  808.           DEBUG(("fseek failure in putcore\n"));
  809.           return(-1);
  810.       }
  811. !     (void) fwrite((char *)tab, SOF, (size_t)conf.tsize, f);
  812.       (void) fflush(f);
  813.       return((ferror(f)) ? -1 : 0);
  814.   }
  815.   
  816.   /*
  817.    - start - set up to start or restart a search
  818. --- 1409,1419 ----
  819.           DEBUG(("fseek failure in putcore\n"));
  820.           return(-1);
  821.       }
  822. !     (void) fwrite((POINTER)tab, SOF, (size_t)conf.tsize, f);
  823.       (void) fflush(f);
  824.       return((ferror(f)) ? -1 : 0);
  825.   }
  826. + #endif
  827.   
  828.   /*
  829.    - start - set up to start or restart a search
  830. ***************
  831. *** 1343,1349 ****
  832.               }
  833.   
  834.               /* read it */
  835. !             if (fread((char *)&val, sizeof(val), 1, pagf) == 1)
  836.                   value = MAPIN(val);
  837.               else if (ferror(pagf)) {
  838.                   DEBUG(("search: read failed\n"));
  839. --- 1491,1497 ----
  840.               }
  841.   
  842.               /* read it */
  843. !             if (fread((POINTER)&val, sizeof(val), 1, pagf) == 1)
  844.                   value = MAPIN(val);
  845.               else if (ferror(pagf)) {
  846.                   DEBUG(("search: read failed\n"));
  847. ***************
  848. *** 1425,1436 ****
  849.       if (corepag != NULL && place < conf.tsize) {
  850.           corepag[place] = value;
  851.           DEBUG(("set: incore\n"));
  852.           return(0);
  853.       }
  854.   
  855.       /* seek to spot */
  856.       pagpos = -1;        /* invalidate position memory */
  857. !     if (fseek(pagf, place * SOF, SEEK_SET) != 0) {
  858.           DEBUG(("set: seek failed\n"));
  859.           sp->aborted = 1;
  860.           return(-1);
  861. --- 1573,1589 ----
  862.       if (corepag != NULL && place < conf.tsize) {
  863.           corepag[place] = value;
  864.           DEBUG(("set: incore\n"));
  865. + #ifdef MMAP
  866.           return(0);
  867. + #else
  868. +         if (!writethrough)
  869. +             return(0);
  870. + #endif
  871.       }
  872.   
  873.       /* seek to spot */
  874.       pagpos = -1;        /* invalidate position memory */
  875. !     if (fseek(pagf, (of_t)(place * SOF), SEEK_SET) != 0) {
  876.           DEBUG(("set: seek failed\n"));
  877.           sp->aborted = 1;
  878.           return(-1);
  879. ***************
  880. *** 1437,1443 ****
  881.       }
  882.   
  883.       /* write in data */
  884. !     if (fwrite((char *)&value, SOF, 1, pagf) != 1) {
  885.           DEBUG(("set: write failed\n"));
  886.           sp->aborted = 1;
  887.           return(-1);
  888. --- 1590,1596 ----
  889.       }
  890.   
  891.       /* write in data */
  892. !     if (fwrite((POINTER)&value, SOF, 1, pagf) != 1) {
  893.           DEBUG(("set: write failed\n"));
  894.           sp->aborted = 1;
  895.           return(-1);
  896. ***************
  897. *** 1474,1479 ****
  898. --- 1627,1633 ----
  899.       u.o = 1;
  900.       for (ntodo = (int)SOF; ntodo > 0; ntodo--) {
  901.           for (i = 0; i < SOF; i++)
  902. +             /* SUPPRESS 112 *//* Retrieving char where long is stored */
  903.               if (u.c[i] != 0)
  904.                   break;
  905.           if (i == SOF) {
  906. ***************
  907. *** 1485,1490 ****
  908. --- 1639,1645 ----
  909.           }
  910.           DEBUG(("mybytemap: byte %d\n", i));
  911.           *--mp = i;
  912. +         /* SUPPRESS 112 *//* Retrieving char where long is stored */
  913.           while (u.c[i] != 0)
  914.               u.o <<= 1;
  915.       }
  916. ***************
  917. *** 1728,1747 ****
  918.       switch (conf.casemap) {
  919.       case '0':        /* unmapped, sensible */
  920.           return(NULL);
  921. -         break;
  922.       case 'C':        /* C News, RFC 822 conformant (approx.) */
  923. !         p = memchr(s, '@', siz);
  924.           if (p == NULL)            /* no local/domain split */
  925.               return(NULL);        /* assume all local */
  926. !         else if    (p - (s+1) == plen && CISTREQN(s+1, post, plen)) {
  927.               /* crazy -- "postmaster" is case-insensitive */
  928.               return(s);
  929. !         } else
  930. !             return(p);
  931. !         break;
  932.       case '=':        /* 2.11, neither sensible nor conformant */
  933.           return(s);    /* all case-insensitive */
  934. -         break;
  935.       }
  936.   
  937.       DEBUG(("cipoint: unknown case mapping `%c'\n", conf.casemap));
  938. --- 1883,1899 ----
  939.       switch (conf.casemap) {
  940.       case '0':        /* unmapped, sensible */
  941.           return(NULL);
  942.       case 'C':        /* C News, RFC 822 conformant (approx.) */
  943. !         p = memchr((POINTER)s, '@', siz);
  944.           if (p == NULL)            /* no local/domain split */
  945.               return(NULL);        /* assume all local */
  946. !         if (p - (s+1) == plen && CISTREQN(s+1, post, plen)) {
  947.               /* crazy -- "postmaster" is case-insensitive */
  948.               return(s);
  949. !         }
  950. !         return(p);
  951.       case '=':        /* 2.11, neither sensible nor conformant */
  952.           return(s);    /* all case-insensitive */
  953.       }
  954.   
  955.       DEBUG(("cipoint: unknown case mapping `%c'\n", conf.casemap));
  956. ***************
  957. *** 1751,1766 ****
  958.   /*
  959.    - dbzdebug - control dbz debugging at run time
  960.    */
  961.   int                /* old value */
  962.   dbzdebug(value)
  963.   int value;
  964.   {
  965. - #ifdef DBZDEBUG
  966.       register int old = debug;
  967.   
  968.       debug = value;
  969.       return(old);
  970. - #else
  971. -     return(-1);
  972. - #endif
  973.   }
  974. --- 1903,1916 ----
  975.   /*
  976.    - dbzdebug - control dbz debugging at run time
  977.    */
  978. + #ifdef DBZDEBUG
  979.   int                /* old value */
  980.   dbzdebug(value)
  981.   int value;
  982.   {
  983.       register int old = debug;
  984.   
  985.       debug = value;
  986.       return(old);
  987.   }
  988. + #endif
  989.